package com.example.zhbj.view;

import android.content.Context;
import android.media.Image;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.zhbj.R;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 下拉刷新ListView
 */
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {

    /**
     * 头布局的高度
     */
    private int mMeasuredHeight;

    /**
     * 头布局对象
     */
    private View mHeadView;

    /**
     * 脚布局的高度
     */
    private int mMeasuredFootHeight;

    /**
     * 脚布局对象
     */
    private View mFootView;

    /**
     * 起始的Y坐标
     */
    private int startY = -1;

    /**
     * 结束的Y坐标
     */
    private int endY;

    /**
     * Y坐标轴的偏移量
     */
    private int dY;

    /**
     * 下拉刷新状态标志位
     */
    private static final int STATE_PULL_TO_REFRESH = 0;

    /**
     * 松开刷新状态标志位
     */
    private static final int STATE_RELEASE_TO_REFRESH = 1;

    /**
     * 正在刷新状态标志位
     */
    private static final int STATE_REFRESHING = 2;

    /**
     * 当前状态的标志位，默认为松开刷新
     */
    private int mCurrentState = STATE_PULL_TO_REFRESH;

    /**
     * 状态文本组件
     */
    private TextView tvState;

    /**
     * 时间文本组件
     */
    private TextView tvTime;

    /**
     * 箭头图标
     */
    private ImageView ivArrow;

    /**
     * 加载条组件
     */
    private ProgressBar pbLoading;

    /**
     * 箭头向上的动画对象
     */
    private RotateAnimation animUp;

    /**
     * 箭头向下的动画对象
     */
    private RotateAnimation animDown;

    /**
     * 监听器回调接口
     */
    private OnRefreshListener mListener;

    /**
     * 标记是否正在加载更多
     */
    private boolean isLoadMore = false;

    public RefreshListView(Context context) {
        this(context, null);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHeaderView();
        initFooterView();
    }

    /**
     * 初始化头布局
     */
    private void initHeaderView(){
        mHeadView = View.inflate(getContext(),R.layout.pull_to_refresh_header,null);
        addHeaderView(mHeadView); // 给ListView添加头布局

        tvState = (TextView) mHeadView.findViewById(R.id.tv_state);
        tvTime = (TextView) mHeadView.findViewById(R.id.tv_time2);
        ivArrow = (ImageView) mHeadView.findViewById(R.id.iv_arrow);
        pbLoading = (ProgressBar) mHeadView.findViewById(R.id.pb_loading);
        /*
        隐藏头布局
        1.获取当前头布局高度
        2.设置负paddingTop，布局就会向上走
         */
        // int height = mHeadView.getHeight(); 不能这样获取宽高，因为没有绘制完毕
        mHeadView.measure(0,0); // 手动测量，宽高传0表示不参与具体宽高的设定，全由系统底层决定
        mMeasuredHeight = mHeadView.getMeasuredHeight(); // 获取测量后的高度
        mHeadView.setPadding(0,-mMeasuredHeight,0,0);

        initArrowAnim();
        setRefreshTime();
    }

    /**
     * 初始化脚布局
     */
    private void initFooterView(){
        mFootView = View.inflate(getContext(),R.layout.pull_to_refresh_foot,null);
        addFooterView(mFootView);

        mFootView.measure(0,0);
        mMeasuredFootHeight = mFootView.getMeasuredHeight();
        // 隐藏脚布局
        mFootView.setPadding(0,-mMeasuredFootHeight,0,0);

        // 设置滑动监听
        setOnScrollListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                startY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (startY == -1){
                    // 没有获取到按下的事件（按住头条新闻滑动时，按下事件被ViewPager消费了）
                    startY = (int) ev.getY(); // 重新获取起点的位置
                }
                endY = (int) ev.getY();
                dY = endY - startY;

                // 如果正在刷新，就什么都不做
                if (mCurrentState == STATE_REFRESHING){
                    break;
                }

                int firstVisiblePosition = this.getFirstVisiblePosition(); // 当前显示的第一个item的位置
                if (dY > 0 && firstVisiblePosition == 0){
                    // 下拉动作 & 当前在ListView的顶部
                    int padding = -mMeasuredHeight + dY;
                    if (padding > 0 && mCurrentState != STATE_RELEASE_TO_REFRESH){
                        // 切换到松开刷新状态
                        mCurrentState = STATE_RELEASE_TO_REFRESH;
                        refreshState();
                    }else if (padding <= 0 && mCurrentState != STATE_PULL_TO_REFRESH){
                        // 切换到下拉刷新状态
                        mCurrentState = STATE_PULL_TO_REFRESH;
                        refreshState();
                    }
                    // 通过修改padding来设置当前刷新控件的最新位置
                    mHeadView.setPadding(0,padding,0,0);
                    return true; // 消费此事件，处理下拉刷新控件的滑动，不需要ListView原生效果参与
                }
                break;
            case MotionEvent.ACTION_UP:
                startY = -1; // 起始坐标归0
                if (mCurrentState == STATE_RELEASE_TO_REFRESH){
                    // 切换成正在刷新
                    mCurrentState = STATE_REFRESHING;
                    // 完整显示刷新控件
                    mHeadView.setPadding(0,0,0,0);
                    refreshState();
                }else if (mCurrentState == STATE_PULL_TO_REFRESH){
                    // 隐藏刷新控件
                    mHeadView.setPadding(0,-mMeasuredHeight,0,0);
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev); // 要返回super，方便ListView原生滑动处理
    }

    /**
     * 初始化箭头动画
     */
    private void initArrowAnim(){
        animUp = new RotateAnimation(0,-180, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        animUp.setDuration(300);
        animUp.setFillAfter(true); // 保持住动画结束的状态

        animDown = new RotateAnimation(-180,0, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        animDown.setDuration(300);
        animDown.setFillAfter(true); // 保持住动画结束的状态
    }

    /**
     * 根据当前状态来刷新界面
     */
    private void refreshState() {
        switch (mCurrentState){
            case STATE_PULL_TO_REFRESH:
                tvState.setText("下拉刷新");
                pbLoading.setVisibility(View.INVISIBLE);
                ivArrow.setVisibility(View.VISIBLE);
                ivArrow.setAnimation(animDown);
                break;
            case STATE_RELEASE_TO_REFRESH:
                tvState.setText("松开刷新");
                pbLoading.setVisibility(View.INVISIBLE);
                ivArrow.setVisibility(View.VISIBLE);
                ivArrow.setAnimation(animUp);
                break;
            case STATE_REFRESHING:
                tvState.setText("正在刷新");
                pbLoading.setVisibility(View.VISIBLE);
                ivArrow.clearAnimation(); // 清理动画之后才能隐藏
                ivArrow.setVisibility(View.INVISIBLE);
                // 回调下拉刷新
                if (mListener != null){
                    mListener.onRefresh();
                }
                break;
            default:
                break;
        }
    }

    /**
     * 刷新结束，隐藏控件
     */
    public void onRefreshComplete(){
        if (!isLoadMore){
            // 隐藏控件
            mHeadView.setPadding(0,-mMeasuredHeight,0,0);

            // 所有状态初始化
            tvState.setText("下拉刷新");
            pbLoading.setVisibility(View.INVISIBLE);
            ivArrow.setVisibility(View.VISIBLE);
            mCurrentState = STATE_PULL_TO_REFRESH;

            // 更新刷新时间
            setRefreshTime();
        }else {
            // 隐藏加载更多的控件
            mFootView.setPadding(0,-mMeasuredFootHeight,0,0);
            isLoadMore = false;
        }




    }

    public void setOnRefreshListener(OnRefreshListener listener){
        mListener = listener;
    }

    /**
     * 滑动状态发生变化
     * @param view
     * @param scrollState
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE){
            // 空闲状态
            int lastPosition = getLastVisiblePosition(); // 当前显示item的最后一个位置
            if (lastPosition == getCount() - 1 && !isLoadMore){
                // 加载了一次数据
                isLoadMore = true;

                // 显示加载中布局
                mFootView.setPadding(0,0,0,0);
                setSelection(getCount() - 1); // 显示在最后一个item的位置（展示加载中布局）

                // 加载更多数据
                if (mListener != null){
                    mListener.onLoadMore();
                }
            }
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }

    // 回调接口，通知刷新状态
    public interface OnRefreshListener{
        // 下拉刷新新的回调
        public void onRefresh();

        // 加载更多数据的回调
        public void onLoadMore();
    }

    // 设置刷新时间
    private void setRefreshTime(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = format.format(new Date());
        tvTime.setText(time);
    }
}
